<template>
  <!-- 弹出框 -->
  <el-dialog :title="title" :visible="visible" @close="close">
    <!-- add,方便父组件找到，并重置表单样式 -->
    <el-form ref="form" label-width="100px" label-position="left" :model="form" :rules="rules">
      <el-form-item label="部门名称" prop="name">
        <el-input v-model.trim="form.name" placeholder="请输入部门名称" />
      </el-form-item>
      <el-form-item label="部门编码" prop="code">
        <el-input v-model.trim="form.code" placeholder="请输入部门编码" />
      </el-form-item>
      <el-form-item label="部门负责人" prop="manager">
        <!-- 为了时效性，获取焦点时，发请求获取负责人信息 -->
        <el-select v-model.trim="form.manager" placeholder="部门负责人" @focus="focusFn">
          <!-- 正常的:value应该是id，因为名字会重复，id是唯一的，这个原因是后台造成的，后台要的是负责人名字 -->
          <el-option
            v-for="item in employeeList"
            :key="item.id"
            :label="item.username"
            :value="item.username"
          />
        </el-select>
      </el-form-item>
      <el-form-item label="部门介绍" prop="introduce">
        <el-input
          v-model.trim="form.introduce"
          resize="none"
          type="textarea"
          rows="3"
          placeholder="请输入部门介绍"
        />
      </el-form-item>
    </el-form>

    <template #footer>
      <el-button @click="close">取 消</el-button>
      <el-button type="primary" @click="submit">确 定</el-button>
    </template>
  </el-dialog>
</template>

<script>
// 获取全部部门
import { getDepartmentList, addDepartment, updateDepartment } from '@/api/departments'
// 获取员工简单列表
import { getEmployeeSimple } from '@/api/employees'
export default {
  props: {
    // 是否显示弹窗
    visible: {
      type: Boolean,
      default: false
    },
    // 点击的当前项
    nodeDate: {
      type: Object,
      required: true
    }
  },
  data() {
    // 校验同级部门中禁止出现重复部门
    const checkName = async(rule, value, callback) => {
      // 为了时效性，发请求拿全部的部门
      const res = await getDepartmentList()
      let sonDepartment
      // 有id，证明是编辑
      if (this.form.id) {
        // 编辑，部门名称要和同级的比较，部门名称可以和原来的一样
        if (value === this.nodeDate.name) {
          return callback()
        }
        // 和同级比较,找到同级部门
        sonDepartment = res.depts.filter(item => item.pid === this.nodeDate.pid)
      } else {
        // 添加，和同级部门比较
        // console.log(res)
        // 查找全部部门的pid，只要等于当前项的id，就是当前项的子部门
        sonDepartment = res.depts.filter(item => item.pid === this.nodeDate.id)
        // console.log(sonDepartment)
      }
      // 只要有一个子部门和输入的相同，就证明部门名重复了
      const isRepeat = sonDepartment.some(item => item.name === value)
      // 判断结果是否是true，是true就是相同了
      if (isRepeat) {
        // 如果相同不通过校验
        callback(new Error(`同级部门下${value}已经存在了`))
      } else {
        // 不相同通过校验
        callback()
      }
    }
    // 校验同级部门中禁止出现重复编码
    const checkCode = async(rule, value, callback) => {
      // 为了时效性，发请求拿全部的部门
      const res = await getDepartmentList()
      // 有id，证明是编辑
      if (this.form.id) {
        // 编码可以和原来的一样，但是不能和其他的一样
        if (value === this.nodeDate.code) {
          // 和自己一样可以，直接return下面代码就可以不执行了
          return callback()
        }
      }
      // console.log(res)
      // 只要有一个编码和输入的相同，就证明部门编码重复了
      const isRepeat = res.depts.some(item => item.code === value)
      // 只要是true就是找到了相同的，就提示错误信息，否者通过校验
      isRepeat ? callback(new Error(`编码${value}已经存在了`)) : callback()
    }
    return {
      form: {
        name: '',
        code: '',
        manager: '',
        introduce: ''
      },
      // 全部负责人
      employeeList: [],
      rules: {
        name: [
          // 不写trigger默认 blur和change都会触发
          { required: true, message: '部门名称不能为空' },
          { max: 50, message: '长度1-50' },
          // 自定义校验，因为要发请求，失去焦点的时候触发
          { validator: checkName, trigger: 'blur' }
        ],
        code: [
          { required: true, message: '部门编码不能为空' },
          { max: 50, message: '长度1-50' },
          // 自定义校验，因为要发请求，失去焦点的时候触发
          { validator: checkCode, trigger: 'blur' }
        ],
        manager: [
          { required: true, message: '部门负责人不能为空' }
        ],
        introduce: [
          { required: true, message: '部门介绍不能为空' },
          { max: 300, message: '长度1-300' }
        ]
      }
    }
  },
  computed: {
    title() {
      return this.form.id ? '编辑部门' : '添加子部门'
    }
  },
  methods: {
    // 通知父组件关闭弹窗
    close() {
      // 用了sync，关闭弹窗
      this.$emit('update:visible', false)
      // 重置表单还需要重置表单的校验,因为是form的方法，需要找到form并且重置
      this.$refs.form.resetFields()
      // 如果点击了编辑部门，拿到了id，再关闭，双向绑定只会清空绑定的内容，因为id没绑定，所以id不会清空，不会清空，点击添加部门也会显示编辑部门
      // 直接给form换一个新对象
      this.form = {
        name: '',
        code: '',
        manager: '',
        introduce: ''
      }
    },
    // 获取员工简单列表
    async focusFn() {
      const res = await getEmployeeSimple()
      // console.log(res)
      this.employeeList = res
    },
    // 提交表单
    async submit() {
      // 校验
      try {
        // 是一个promise，如果校验通过了是true，校验没通过是false而且会报错
        await this.$refs.form.validate()
      } catch {
        return
      }
      // 有id，是编辑
      if (this.form.id) {
        await updateDepartment(this.form)
      } else {
        // 否者是添加
        // 校验通过 发请求添加 因为传递的是一个对象，form中只有四项，外加一项当前项的id
        await addDepartment({
          ...this.form,
          // pid是就父id，当前项的id
          pid: this.nodeDate.id
        })
      }
      // 给提示，关闭弹窗，通知父组件刷新
      this.$message.success('操作成功')
      // 用了sync，关闭弹窗
      this.$emit('update:visible', false)
      this.$emit('getDepartments')
    }
  }
}
</script>

<style>

</style>
